<template>
  <div class="slider" ref="slider">
    <div class="process" v-model="progress" ref="process" :style="{width}"></div>
    <div class="thunk" ref="trunk" :style="{left}">
      <div class="block"></div>
      <div class="tips">
        <span>{{progress}}</span>
        <i class="fas fa-caret-down"></i>
      </div>
    </div>
  </div>
</template>
<script>
export default {
  props: ["value"],
  data() {
    return {
      sliderElem: null, //滚动条DOM元素
      thunkElem: null, //拖拽DOM元素
      processElem: null,
      progress: this.value, //当前值（占比）
      width: 0,   //滚动条DOM元素的宽
      left: 0,    //拖拽DOM元素的left
      min: 0,     //滑动最小值
      max: 0,      //滑动最大值
      changeEvent : null,
      vModel : null
    };
  },
  methods: {
    /**
     * 鼠标移动事件
     */
    sliderTouchmove(e) {
      //偏移量
      let cDx = (e.clientX || e.touches[0].clientX) - this.trunkV;;
      cDx >= this.max && (cDx = this.trunkWidth); //限制最小值
      cDx <= this.min && (cDx = this.min);      //限制最大值
      this.width = cDx + "px";    //赋值滚动条DOM的width
      this.left = cDx - 10 + "px";  //赋值拖拽DOM元素的left值
      this.progress = Math.floor((cDx / this.trunkWidth) * 100); //计算当前占比
    },
    /**
     * 鼠标抬起事件
     */
    sliderTouchend(e) {
      this.sliderElem.removeEventListener("touchmove", this.sliderTouchmove, false);
      this.sliderElem.removeEventListener("touchend", this.sliderTouchend, false);
    }
  },
  mounted() {
    this.sliderElem = this.$refs.slider;
    this.trunkElem = this.$refs.trunk;
    this.processElem = this.$refs.process;
    var _this = this;
    this.trunkWidth = this.sliderElem.offsetWidth;
    var initValue = (this.progress / 100) * this.trunkWidth;
    this.min = this.$attrs.min || initValue;
    this.max = this.$attrs.max || this.trunkWidth;
    this.width = initValue + "px";
    this.left = initValue - 10 + "px";
    this.trunkElem.addEventListener(
      "touchstart",
      function(e) {
        _this.trunkV = _this.sliderElem.offsetLeft; //距离左边距离
        _this.sliderElem.addEventListener("touchmove", _this.sliderTouchmove, false);
        _this.sliderElem.addEventListener("touchend", _this.sliderTouchend, false);
      },
      false
    );
    this.trunkElem.onmousedown = function(e) {
      _this.trunkV = _this.sliderElem.offsetLeft; //距离左边距离
      document.onmousemove = _this.sliderTouchmove;
      document.onmouseup = function() {
        document.onmousemove = document.onmouseup = null;
      };
    };
  },
  created() {
    this.$options._parentVnode.data.model != null && ( this.vModel = this.$options._parentVnode.data.model.expression);
    this.$listeners.change != null && (this.changeEvent = this.$listeners.change.fns.name.split(" ")[1]);
    this.$attrs.value = this.progress;
  },
  watch: {
    progress: function() {
      this.vModel != null && (this.$parent._data[this.vModel] = this.progress);
      this.changeEvent != null && (this.$parent[this.changeEvent](this.progress));
      this.$attrs.value = this.progress;
    }
  }
};
</script>
<style>
.box {
  margin: 100px auto 0;
  width: 80%;
}
.clear:after {
  content: "";
  display: block;
  clear: both;
}
.slider {
  position: relative;
  margin: 20px 0;
  width: 400px;
  height: 10px;
  background: #e4e7ed;
  border-radius: 5px;
  cursor: pointer;
}
.slider .process {
  position: absolute;
  left: 0;
  top: 0;
  width: 112px;
  height: 10px;
  border-radius: 5px;
  background: #409eff;
}
.slider .thunk {
  position: absolute;
  left: 100px;
  top: -7px;
  width: 20px;
  height: 20px;
}
.slider .block {
  width: 20px;
  height: 20px;
  border-radius: 50%;
  border: 2px solid #409eff;
  background: rgba(255, 255, 255, 1);
  transition: 0.2s all;
}
.slider .tips {
  position: absolute;

  bottom: 0;
  min-width: 20px;
  text-align: center;
  border-radius: 5px;
  height: 20px;
  font-size: 12px;
  line-height: 20px;
  color: #000;
}
.slider .tips i {
  position: absolute;
  margin-left: -5px;
  left: 50%;
  bottom: -9px;
  font-size: 16px;
  color: #000;
}
.slider .block:hover {
  transform: scale(1.1);
  opacity: 0.6;
}
</style>